﻿using DVPCameraType;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing.Imaging;

namespace DataCodeDemo.CamDrives
{
    public class DVPCamUsbDrive : ICam
    {
        static uint m_handle;//相机句柄

        /// <summary>
        /// 获取图像
        /// </summary>
        /// <returns></returns>
        public OperateResult<ImageInfo> AcquireImage()
        {
            dvpStreamState state = dvpStreamState.STATE_STOPED;
            dvpStatus status;
            dvpFrame refFrame = new dvpFrame();
            IntPtr pBuffer = new IntPtr();
            if (IsValidHandle(m_handle))
            {
                status = DVPCamera.dvpGetStreamState(m_handle, ref state);
                if (state == dvpStreamState.STATE_STOPED)
                {
                    status = DVPCamera.dvpStart(m_handle);
                }
                if (status == dvpStatus.DVP_STATUS_OK)
                {
                    try
                    {
                        status = DVPCamera.dvpTriggerFire(m_handle);
                        if (status == dvpStatus.DVP_STATUS_OK)
                        {
                            status = DVPCamera.dvpGetFrame(m_handle, ref refFrame, ref pBuffer, 10000);
                            if (status == dvpStatus.DVP_STATUS_OK)
                            {
                                zwxImageFormat zwxImageFormat = 0;
                                if (refFrame.format == dvpImageFormat.FORMAT_BGR24)
                                {
                                    zwxImageFormat = zwxImageFormat.FORMAT_BGR24;
                                }
                                else if (refFrame.format == dvpImageFormat.FORMAT_MONO)
                                {
                                    zwxImageFormat = zwxImageFormat.FORMAT_MONO;
                                }
                                return OperateResult.CreateSuccessResult(new ImageInfo
                                {
                                    FrameInfo = new FrameInfo
                                    {
                                        format = zwxImageFormat,
                                        bRotateState = refFrame.bRotateState == 0x01,
                                        iHeight = refFrame.iHeight,
                                        iWidth = refFrame.iWidth,
                                    },
                                    ImageBuffer = pBuffer
                                });
                            }
                            else return new OperateResult<ImageInfo>("获取图像失败");
                        }
                        else return new OperateResult<ImageInfo>("触发相机失败");
                    }
                    catch (Exception ex)
                    {
                        DVPCamera.dvpStop(m_handle);
                        throw;
                    }
                }
                else return new OperateResult<ImageInfo>("开启图像输出功能失败");

            }
            else return new OperateResult<ImageInfo>("相机未初始化");
        }

        public OperateResult<Bitmap> AcquireImage2()
        {
            dvpStreamState state = dvpStreamState.STATE_STOPED;
            dvpStatus status;
            dvpFrame refFrame = new dvpFrame();
            IntPtr pBuffer = new IntPtr();
            if (IsValidHandle(m_handle))
            {
                status = DVPCamera.dvpGetStreamState(m_handle, ref state);
                if (state == dvpStreamState.STATE_STOPED)
                {
                    status = DVPCamera.dvpStart(m_handle);
                }
                if (status == dvpStatus.DVP_STATUS_OK)
                {
                    status = DVPCamera.dvpTriggerFire(m_handle);
                    if (status == dvpStatus.DVP_STATUS_OK)
                    {
                        status = DVPCamera.dvpGetFrame(m_handle, ref refFrame, ref pBuffer, 10000);
                        if (status == dvpStatus.DVP_STATUS_OK)
                        {
                            int width = refFrame.iWidth;
                            int height = refFrame.iHeight;
                            int stride;
                            Bitmap bitmap;
                            //图像是否旋转了90度，旋转了90度帧宽度和高度要互换
                            if (refFrame.bRotateState != 0x00)
                            {
                                height = refFrame.iWidth;
                                width = refFrame.iHeight;
                            }
                            if (refFrame.format == dvpImageFormat.FORMAT_BGR24)
                            {
                                stride = ((width * 3 - 1) / 4) * 4 + 4;
                                bitmap = new Bitmap(width, height, stride, PixelFormat.Format24bppRgb, pBuffer);
                            }
                            else if (refFrame.format == dvpImageFormat.FORMAT_MONO)
                            {
                                stride = ((width - 1) / 4) * 4 + 4;
                                bitmap = new Bitmap(width, height, stride, PixelFormat.Format8bppIndexed, pBuffer);
                            }
                            else return new OperateResult<Bitmap>("图像格式有误");
                            return OperateResult.CreateSuccessResult(bitmap);
                        }
                        else return new OperateResult<Bitmap>("获取图像失败");
                    }
                    else return new OperateResult<Bitmap>("触发相机失败");
                }
                else return new OperateResult<Bitmap>("开启图像输出功能失败");
            }
            else return new OperateResult<Bitmap>("相机未初始化");
        }

        /// <summary>
        /// 关闭相机
        /// </summary>
        /// <returns></returns>
        public OperateResult CloseCam()
        {
            if (IsValidHandle(m_handle))
            {
                dvpStatus status = DVPCamera.dvpClose(m_handle);
                if (status == dvpStatus.DVP_STATUS_OK)
                {
                    return OperateResult.CreateSuccessResult();
                }
                else return new OperateResult("相机关闭失败");
            }
            else return new OperateResult("相机未初始化");
        }

        /// <summary>
        /// 获取相机列表信息
        /// </summary>
        /// <returns></returns>
        public OperateResult<List<CameraInfos>> GetCameras()
        {
            uint i, n = 0;
            dvpStatus status;
            status = DVPCamera.dvpRefresh(ref n);
            if (status == dvpStatus.DVP_STATUS_OK)
            {
                for (i = 0; i < n; i++)
                {
                    dvpCameraInfo dev_info = new dvpCameraInfo();
                    status = DVPCamera.dvpEnum(i, ref dev_info);
                    if (status == dvpStatus.DVP_STATUS_OK)
                    {
                        List<CameraInfos> cameraInfos = new List<CameraInfos>
                        {
                            new CameraInfos
                            {
                                Vendor = dev_info.Vendor,
                                Manufacturer = dev_info.Manufacturer,
                                Model = dev_info.Model,
                                Family = dev_info.Family,
                                LinkName = dev_info.LinkName,
                                SensorInfo = dev_info.SensorInfo,
                                HardwareVersion = dev_info.HardwareVersion,
                                FriendlyName = dev_info.FriendlyName,
                                KernelVersion = dev_info.KernelVersion,
                                DscamVersion = dev_info.DscamVersion,
                                FirmwareVersion = dev_info.FirmwareVersion,
                                PortInfo = dev_info.PortInfo,
                                SerialNumber = dev_info.SerialNumber,
                                CameraInfo = dev_info.CameraInfo,
                                UserID = dev_info.UserID,
                                reserved = dev_info.reserved
                            }
                        };
                        return OperateResult.CreateSuccessResult(cameraInfos);
                    }
                }
            }
            return new OperateResult<List<CameraInfos>>("失败");
        }

        /// <summary>
        /// 打开相机
        /// </summary>
        /// <param name="camera"></param>
        /// <returns></returns>
        public OperateResult OpenCam(CameraInfos camera)
        {
            dvpStatus status;
            if (!IsValidHandle(m_handle))
            {
                status = DVPCamera.dvpOpenByName(camera.FriendlyName, dvpOpenMode.OPEN_NORMAL, ref m_handle);
                if (status == dvpStatus.DVP_STATUS_OK)
                {
                    return OperateResult.CreateSuccessResult();
                }
                else return new OperateResult("相机打开失败");
            }
            else return new OperateResult("相机已打开");
        }

        /// <summary>
        /// 打开相机参数设置对话框
        /// </summary>
        /// <param name="parent"></param>
        /// <returns></returns>
        public OperateResult ShowPropertyModalDialog(IntPtr parent)
        {
            dvpStatus status;
            if (IsValidHandle(m_handle))
            {
                status = DVPCamera.dvpShowPropertyModalDialog(m_handle, parent);
                if (status == dvpStatus.DVP_STATUS_OK)
                {
                    return OperateResult.CreateSuccessResult();
                }
                else return OperateResult.CreateFailedResult();
            }
            else return new OperateResult("相机未初始化");
        }

        /// <summary>
        /// 检查相机句柄
        /// </summary>
        /// <param name="handle"></param>
        /// <returns></returns>
        private bool IsValidHandle(uint handle)
        {
            bool bValidHandle = false;
            dvpStatus status = DVPCamera.dvpIsValid(handle, ref bValidHandle);
            if (status == dvpStatus.DVP_STATUS_OK)
            {
                return bValidHandle;
            }
            return false;
        }
    }
}
